Azure Front Door — Custom Domain TLS Troubleshooting
Reference guide for diagnosing NET::ERR_CERT_COMMON_NAME_INVALID and related TLS issues on AFD custom domains.
Symptom
Browser reports NET::ERR_CERT_COMMON_NAME_INVALID for a custom domain (e.g. app.example.com) despite the AFD portal showing the domain as provisioned and the certificate as deployed.
Diagnostic Procedure
1. Confirm the correct Azure subscription
AFD resources may live in a different tenant or subscription than expected. Always set the correct subscription before running any az afd commands:
az account set --subscription "<subscription-id>"
az account show --query "{name:name, id:id}" --output tableExample output:
Name Id
------------------- ------------------------------------
Contoso Production a1b2c3d4-e5f6-7890-abcd-ef12345678902. List custom domains and their internal resource names
AFD resource names replace dots with hyphens and may include a random suffix. Always list first to get the exact name:
az afd custom-domain list \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--query "[].{name:name, hostname:hostName}" \
--output tableExample output:
Name Hostname
--------------------- -----------------
app-example-com-7k2m app.example.com
api-example-com-9p1q api.example.com3. Check custom domain provisioning and certificate state
az afd custom-domain show \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--custom-domain-name <name-from-step-2> \
--query "{provisioningState:provisioningState, validationState:domainValidationState, deploymentStatus:deploymentStatus, certificateType:tlsSettings.certificateType}" \
--output jsonExpected healthy output:
{
"certificateType": "ManagedCertificate",
"deploymentStatus": "Succeeded",
"provisioningState": "Succeeded",
"validationState": "Approved"
}Example when validation or cert deployment is still in progress (values vary):
{
"certificateType": "ManagedCertificate",
"deploymentStatus": "NotStarted",
"provisioningState": "Succeeded",
"validationState": "Pending"
}4. Check endpoint deployment status
Even if the custom domain looks healthy, the endpoint itself may not have propagated to AFD POPs:
az afd endpoint show \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--endpoint-name <endpoint-name> \
--query "{deploymentStatus:deploymentStatus, provisioningState:provisioningState}" \
--output tableExample when propagation is still pending:
DeploymentStatus ProvisioningState
------------------ -------------------
NotStarted SucceededExample when the endpoint is fully deployed:
DeploymentStatus ProvisioningState
------------------ -------------------
Succeeded SucceededDeploymentStatus: NotStarted means the configuration has not propagated to edge nodes yet — this is the most common cause of the cert mismatch even when everything else appears healthy.
5. Check the cert actually being served
openssl s_client -connect app.example.com:443 -servername app.example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates| CN in output | Meaning |
|---|---|
app.example.com | AFD is serving the correct custom domain cert — healthy |
*.azureedge.net | AFD is receiving the request but serving the default endpoint cert — propagation pending or route misconfiguration |
| Anything else | Traffic is not reaching AFD — check DNS |
Example when the custom domain cert is live (subject CN matches your hostname):
subject=CN = app.example.com
issuer=C = US, O = Microsoft Corporation, CN = Microsoft Azure ECC TLS Issuing CA 03 - x
notBefore=Apr 1 12:00:00 2026 GMT
notAfter=Jun 30 12:00:00 2026 GMTExample when AFD is still serving the default endpoint certificate (symptom lines up with *.azureedge.net / edge default):
subject=CN = *.azurefd.net
issuer=C = US, O = Microsoft Corporation, CN = Microsoft Azure RSA TLS Issuing CA 07 - x
notBefore=Mar 15 00:00:00 2026 GMT
notAfter=Jun 13 23:59:59 2026 GMT(Exact issuer strings change over time; focus on subject= / CN.)
6. Check DNS is pointing to AFD
dig app.example.com +shortExpected: A CNAME chain resolving through *.azurefd.net, e.g.:
prod-web-a01.azurefd.net.
mr-a01.tm-azurefd.net.
152.199.4.33Example when DNS still points at a bare IP (A record at the apex or wrong target — not the AFD hostname):
20.50.120.88If an IP address is returned directly (no CNAME), the DNS record is still an A record pointing at the old origin (e.g. App Gateway). It must be changed to a CNAME.
7. Verify the custom domain is associated with the correct route
az afd route show \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--endpoint-name <endpoint-name> \
--route-name <route-name> \
--query "customDomains" \
--output jsonExample output (custom domain is linked to the route):
[
"/subscriptions/a1b2c3d4-e5f6-7890-abcd-ef1234567890/resourceGroups/rg-connectivity/providers/Microsoft.Cdn/profiles/contoso-afd/customDomains/app-example-com-7k2m"
]Example when the domain is not on the route (empty array):
[]The custom domain resource ID should appear in the array. If it is missing, the domain needs to be added to the route in the portal or via:
az afd route update \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--endpoint-name <endpoint-name> \
--route-name <route-name> \
--custom-domains <custom-domain-resource-name>8. Force redeployment if endpoint is stuck on NotStarted
A no-op route update triggers a fresh deployment:
az afd route update \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--endpoint-name <endpoint-name> \
--route-name <route-name> \
--https-redirect EnabledThen poll until DeploymentStatus moves to Succeeded:
az afd endpoint show \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--endpoint-name <endpoint-name> \
--query "{deploymentStatus:deploymentStatus, provisioningState:provisioningState}" \
--output tableExpected progression: NotStarted → InProgress → Succeeded
Example while deployment is running:
DeploymentStatus ProvisioningState
------------------ -------------------
InProgress SucceededQuick Reference — All Domains Status
az afd custom-domain list \
--resource-group <resource-group> \
--profile-name <afd-profile-name> \
--query "[].{name:name, provisioningState:provisioningState, validationState:domainValidationState, deploymentStatus:deploymentStatus}" \
--output tableExample output:
Name ProvisioningState ValidationState DeploymentStatus
--------------------- ------------------- ----------------- ----------------
app-example-com-7k2m Succeeded Approved Succeeded
api-example-com-9p1q Succeeded Approved Succeeded
staging-example-com Succeeded Pending NotStartedDecision Tree
Browser TLS error on custom domain
│
├── dig shows A record (not CNAME)?
│ └── Fix DNS → add CNAME to AFD endpoint hostname
│
├── openssl CN = something other than *.azureedge.net?
│ └── Traffic not reaching AFD → check DNS / App Gateway routing
│
├── openssl CN = *.azureedge.net?
│ ├── Custom domain associated with route? (step 7)
│ │ └── No → add domain to route
│ └── Endpoint DeploymentStatus = NotStarted? (step 4)
│ └── Yes → force redeployment (step 8) and wait
│
└── All checks pass, openssl CN = correct domain?
└── Working correctly ✓Notes
- Portal showing “Traffic is delivered securely” reflects the domain resource state, not whether the cert is being served correctly at the edge. Always verify with
openssl. - AFD managed cert propagation after domain validation approval can take 10–30 minutes to reach all POPs.
- The
az afd domainsubcommand does not exist — the correct subcommand isaz afd custom-domain. - Resource names in the CLI use hyphens instead of dots and may include a random suffix (e.g.
app-example-com-6353). Alwayslistfirst to get the exact name. - AFD resources may live in a different subscription/tenant than your primary one — confirm with
az account showbefore running commands.